//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <ddk.h>
#include <errno.h>
#include "CBasicFileSystem.h"
#define IncrementDllLockCount() do {} while(0)
#define DecrementDllLockCount() do {} while(0)
#include "_CKtfsFileSystem.cpp"
#include "CBasicDirectory.h"
#include "CBasicFile.h"

static WString szDisk[5] = {L".", L"D", L"E", L"F", L"G"};

CKtfsFileSystem::CKtfsFileSystem() : m_iDiskNo(0)
{
}

CKtfsFileSystem::CKtfsFileSystem(int iDiskNo) : m_iDiskNo (iDiskNo)
{
}

CKtfsFileSystem::~CKtfsFileSystem()
{
}

ECode CKtfsFileSystem::Sync()
{
    return E_NOT_IMPLEMENTED;
}

ECode CKtfsFileSystem::GetRoot(
                /* [out] */ IBasicDirectory * * piRoot)
{
    CKtfsDirectory *pBasicDir;
    int iDiskNo = m_iDiskNo;
    assert((iDiskNo >= 0) && (iDiskNo < 5));

    if (piRoot == NULL) {
        return E_INVALID_ARGUMENT;
    }
    pBasicDir = new CKtfsDirectory(szDisk[iDiskNo]);
    if (pBasicDir == NULL) {
        return E_OUT_OF_MEMORY;
    }
    *piRoot = pBasicDir;
    return NOERROR;
}

ECode CKtfsFileSystem::Lookup(
                /* [in] */ WString wstrPath,
                /* [out] */ IBasicFile * * piBasicFile)
{
    ECode ec = NOERROR;
    CKtfsDirectory *pBasicDir;
    CKtfsFile *pBasicFile;

    int iDiskNo;
    UInt32 attr;

    if (NULL == wstrPath || !piBasicFile) {
        return E_INVALID_ARGUMENT;
    }
    iDiskNo = m_iDiskNo;
    assert (iDiskNo >= 0 && iDiskNo < 5);

    WStringBuf *pwsPathName = WStringBuf::Alloc(_MAX_PATH);
    if (!pwsPathName) {
        return E_OUT_OF_MEMORY;
    }
    pwsPathName->Copy(szDisk[iDiskNo]);

    pwsPathName->Append(L"\\");
    pwsPathName->Append(wstrPath);
    attr = IO_GetFileAttributes((WChar *)(*pwsPathName));

    if (attr == 0xffffffff) {  //file does not exist
        ec = ECODE_FROM_ERRNO(ENOENT);
        goto L_EXIT;
    }
    if (attr & IO_FA_DIRECTORY) {
        pBasicDir = new CKtfsDirectory(*pwsPathName);
        if (pBasicDir == NULL) {
            ec = E_OUT_OF_MEMORY;
            goto L_EXIT;
        }
        pBasicDir->AddRef();
        *piBasicFile = (IBasicFile *)pBasicDir;
        ec = NOERROR;
        goto L_EXIT;
    }
    else {
        pBasicFile = new CKtfsFile(*pwsPathName, TRUE, TRUE);
        if (pBasicFile == NULL) {
            ec = E_OUT_OF_MEMORY;
            goto L_EXIT;
        }
        pBasicFile->AddRef();
        *piBasicFile = pBasicFile;
        ec = NOERROR;
    }

L_EXIT:
    WStringBuf::Free(pwsPathName);
    return ec;
}

ECode CKtfsFileSystem::BindDriver(
                /* [in] */ WString wstrDevName)
{
    return NOERROR;
}

ECode CKtfsFileSystem::UnbindDriver()
{
    return NOERROR;
}

void CKtfsFileSystem::SetStub(IStub *pStub)
{
    m_pStub = pStub;
}

IStub *CKtfsFileSystem::GetStub()
{
    return m_pStub;
}

ECode CKtfsFileSystem::GetStat(
                /* [out] */ FileSystemStat * pFileSystemStat)
{
    return NOERROR;
}

ECode CKtfsFileSystem::CalcFreeSpace(
                /* [out] */ UInt64 * pTotalNumberOfBytes,
                /* [out] */ UInt64 * pTotalNumberOfFreeBytes)
{
    if (IO_GetDiskFreeSpace (NULL, NULL, (PULARGE_INTEGER)pTotalNumberOfBytes,
                    (PULARGE_INTEGER)pTotalNumberOfFreeBytes)) {
        return NOERROR;
    }
    else {
        return E_FAIL;
    }
}
